package busterminal.persistence.jdbc;

import busterminal.entity.AbstractEntity;
import busterminal.exception.DatabaseException;
import busterminal.persistence.AbstractDAO;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
 * Предок интерфейсов Data Access Object для хранения объектов в базе данных
 */
public abstract class AbstractJdbcDAO<EntityType extends AbstractEntity> implements AbstractDAO<EntityType> {

    /**
     * Класс драйвера, используемый для соединения
     */
    private final static String DRIVER_CLASS = "org.hsqldb.jdbcDriver";
    /**
     * Полный путь к базе данных
     */
    private final static String DB_URL = "jdbc:hsqldb:C:/Workspace/BusTerminal/DataBase/db";
    /**
     * Имя пользователя
     */
    private final static String DB_USER = "SA";
    /**
     * Пароль
     */
    private final static String DB_PASSWORD = "";
    /**
     * Объект {@link java.sql.Connection}, используемый для выполнения запросов к базе данных
     */
    private static Connection connection;

    /**
     * Установить соединение с базой данных
     */
    public static Connection getConnection() {
        if (connection == null) {
            try {
                Class.forName(DRIVER_CLASS);
                connection = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            } catch (Exception e) {
                throw new DatabaseException("Cannot get connection", e);
            }
        }
        return connection;
    }

    /**
     * Закрыть соединение с базой данных
     */
    public static void closeConnection() {
        Statement statement = null;
        try {
            if (connection != null && !connection.isClosed()) {
                statement = connection.createStatement();
                statement.execute("SHUTDOWN");
                connection.close();
            }
        } catch (Exception e) {
            throw new DatabaseException("Cannot close connection", e);
        } finally {
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException ex) {
                System.err.println("Cannot close statement");
                ex.printStackTrace(System.err);
            }
        }
    }

    /**
     * Получить следующий свободный идентификатор для сущности
     * @return свободный идентификатор
     */
    public static int getNextId() {
        Connection cn = getConnection();
        Statement st = null;
        ResultSet rs = null;
        try {
            st = cn.createStatement();
            rs = st.executeQuery("SELECT Value FROM Params WHERE Key='EntityId'");
            int id = 0;
            if (rs.next()) {
                id = rs.getInt("Value");
            } else {
                // to do: think of
            }
            id++;
            st.execute("UPDATE Params SET Value=" + id + " WHERE Key='EntityId'");
            return id;
        } catch (SQLException e) {
            throw new DatabaseException("Cannot create new ID", e);
        } finally {
            try {
                if (rs != null) {
                    rs.close();
                }
                if (st != null) {
                    st.close();
                }
            } catch (SQLException ex) {
                System.err.println("Cannot close statement");
                ex.printStackTrace(System.err);
            }
        }
    }
}
